home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 351-375 / disk_360 / uucp / uucp0.lzh / src / anews / news.c < prev    next >
C/C++ Source or Header  |  1990-05-18  |  7KB  |  410 lines

  1.  
  2. /*
  3.  *  ANEWS -r rows -c cols -p group
  4.  */
  5.  
  6. #include "news.h"
  7. #include <ctype.h>
  8. #include <libraries/dos.h>
  9. #include <getfiles.h>
  10.  
  11. IDENT(".03");
  12.  
  13. #define ON        scr_inverse_on()
  14. #define OFF        scr_inverse_off()
  15. #define Clear_eol    printf("\x9bK")
  16. #define Clear_Screen    printf("\x9bH\x9bJ")
  17. #define Cr        putchar('\r')
  18. #define PROG_NAME    "Anews"
  19.  
  20. char *NewsDir;
  21. char fg, bg;
  22.  
  23. int NumRows = 22;
  24. int NumCols = 77;
  25.  
  26. dir_list *groups;
  27.  
  28. void
  29. initgroups(void)
  30. {
  31.     dir_list *gp;
  32.     int len;
  33.     FILE *fp;
  34.     char buf[50];
  35.  
  36.     if (groups != NULL)
  37.     return;
  38.  
  39.     if ((fp = openlib("newsgroups")) == NULL) {
  40.     puts("Couldn't open LIB/newsgroups file");
  41.     exit(2);
  42.     }
  43.  
  44.     gp = (dir_list *)&groups;
  45.     while (fgets(buf, (int)sizeof buf, fp) != NULL) {
  46.     len = strlen(buf) - 1;
  47.     buf[len] = '\0';
  48.     if ((gp->next = (dir_list *)malloc(4 + len + 1)) == NULL) {
  49.         puts("Malloc failed!");
  50.         exit(4);
  51.     }
  52.     gp = gp->next;
  53.     strcpy(gp->name, buf);
  54.     }
  55.     gp->next = NULL;
  56.  
  57.     fclose(fp);
  58. }
  59.  
  60. static char *
  61. ng(register int i)
  62. {
  63.     register dir_list *gp;
  64.     register int II = i;
  65.     static char *NAME;
  66.     static int I = -1;
  67.  
  68.     if (i == I)
  69.     return NAME;
  70.  
  71.     for (gp = (dir_list *)&groups; (gp = gp->next) != NULL; ) {
  72.     if (--i < 0) {
  73.         I = II;
  74.         return (NAME = gp->name);
  75.     }
  76.     }
  77.     return NULL;
  78. }
  79.  
  80. static char *GroupHelp[] = {
  81.     "y/Y    Read this newsgroup (default)",
  82.     "n/N    Skip this newsgroup",
  83.     "-      Go back to previous news group",
  84.     "^      Go back to first news group",
  85.     "=      List article subjects in this newsgroup",
  86.     "p      Post to this news group",
  87.     "h/H/?  Display help",
  88.     "q/Q    Quit to DOS\n",
  89.     0
  90. };
  91.  
  92. int
  93. main(ac, av)
  94. char **av;
  95. {
  96.     int ch, cnt, nbr;
  97.     char *curgp;
  98.     int found1 = 0;
  99.     int current = -1;
  100.     int old, last = 0;
  101.     short i;
  102.     short notdone = 1;
  103.  
  104.     for (i = 1; i < ac; ++i) {
  105.     char *ptr = av[i];
  106.  
  107.     if (*ptr == '-') {
  108.         ptr += 2;
  109.         switch(ptr[-1]) {
  110.         case 'p':
  111.         if (*ptr)
  112.             reply(0, NULL, ptr);
  113.         else
  114.             reply(0, NULL, av[++i]);
  115.         notdone = 0;
  116.         break;
  117.         case 'r':
  118.         if (*ptr)
  119.             NumRows = atoi(ptr);
  120.         else
  121.             NumRows = atoi(av[++i]);
  122.         break;
  123.         case 'c':
  124.         if (*ptr)
  125.             NumCols = atoi(ptr);
  126.         else
  127.             NumCols = atoi(av[++i]);
  128.         break;
  129.         }
  130.     }
  131.     }
  132.  
  133.     if (notdone == 0) {
  134.     cooked(stdin);
  135.     exit(1);
  136.     }
  137.  
  138.     init();
  139.  
  140.     for (;;) {
  141.     NewGroup:
  142.     if ((curgp = ng(++current)) == NULL) {
  143.         if (!found1) {
  144.         puts("No News, use 'anews -p group' to post new articles");
  145.         do_quit();
  146.         } else {
  147.         found1 = 0, current = -1;
  148.         continue;
  149.         }
  150.     }
  151.  
  152.     while ((nbr = scan_directory(curgp)) != 0) {
  153.         old = last, last = current;
  154.         RepeatGroup:
  155.         Cr, Clear_eol;
  156.         ON;
  157.         cnt = unread_count();
  158.         printf("%d articles in %s (%d unread)? [%s]",
  159.         nbr, curgp, cnt, (cnt == 0) ? "n/y" : "y/n"
  160.         );
  161.         OFF;
  162.         putchar(' ');
  163.         ch = rawch();
  164.         if (ch == ' ')
  165.         ch = (cnt == 0) ? 'n' : 'y';
  166.  
  167.         switch (ch) {
  168.         case 'y':
  169.         case 'Y':
  170.         ++found1;
  171.         if (cnt == 0)
  172.             rewind_arts();
  173.         ch = readgroup(curgp);
  174.         if (ch == 'q')
  175.             do_quit();
  176.         if (ch == '$')
  177.             goto NewGroup;
  178.         if (ch)
  179.             break;
  180.         /* Fall through to... */
  181.         case 'q':
  182.         case 'Q':
  183.         putchar('\n');
  184.         do_quit();
  185.         case 'n':
  186.         case 'N':
  187.         putchar('\n');
  188.         goto NewGroup;
  189.         case '^':
  190.         current = -1;
  191.         goto NewGroup;
  192.         case '-':
  193.         current = old - 1;
  194.         goto NewGroup;
  195. /* FIXME add case to go directly to a specific (named) news group */
  196.         case 'h':
  197.         case 'H':
  198.         case '?':
  199.         do_help(GroupHelp);
  200.         goto RepeatGroup;
  201.         case '=':
  202.         putchar('\n');
  203.         scan_subjects(curgp);
  204.         goto RepeatGroup;
  205.         case 'p':
  206.         putchar('\n');
  207.         reply(0, NULL, curgp);
  208.         goto RepeatGroup;
  209.         }
  210.     }
  211.     }
  212.     return 0;
  213. }
  214.  
  215. char *
  216. Get_Env(char *envar, char *def)
  217. {
  218.     char *p, *eptr;
  219.  
  220.     if ((p = getenv(envar)) != NULL) {
  221.     eptr = (char *)malloc(strlen(p) + 1);
  222.     strcpy(eptr, p);
  223.     } else {
  224.     eptr = def;
  225.     }
  226.     return(eptr);
  227. }
  228.  
  229. void
  230. init()
  231. {
  232.     NewsDir = GetConfigDir(UUNEWS);
  233.     if (access(NewsDir, 0) == -1) {
  234.     printf("FATAL - couldn't access %s\n", NewsDir);
  235.     exit(1);
  236.     }
  237.     fg = *Get_Env("FG", "8");
  238.     bg = *Get_Env("BG", "0");
  239.     initgroups();
  240. }
  241.  
  242. static char buf[BUFSIZ];
  243.  
  244. char *
  245. subs(char *newsfile)
  246. {
  247.     FILE *fp;
  248.     int j;
  249.  
  250.     if ((fp = fopen(newsfile, "r")) == NULL) {
  251.     printf("Couldn't open %s\n", newsfile);
  252.     return(NULL);
  253.     }
  254.     j = 0;
  255.     while ( (j++<50) && (fgets(buf, (int)sizeof buf, fp) != NULL)) {
  256.     if (strncmp("Subject:", buf, 8) == 0) {
  257.         buf[strlen(buf)-1] = '\0';
  258.         fclose(fp);
  259.         return (buf + 8);
  260.     }
  261.     }
  262.     fclose(fp);
  263.     return NULL;
  264. }
  265.  
  266. void
  267. do_quit(void)
  268. {
  269.     exit(0);
  270. }
  271.  
  272. void
  273. do_help(char **pp)
  274. {
  275.     printf("\x9bH\x9bJ\033[0;1;33;40m\r");
  276.     do {
  277.     puts(*pp);
  278.     } while (*++pp != NULL);
  279.     printf("\033[0;31;40m");
  280. }
  281.  
  282. char *
  283. art2file(char *group, char *art)
  284. {
  285.     static char path[128];
  286.  
  287.     sprintf(path, "%s/%s", expand_path(NewsDir, group), art);
  288.     return path;
  289. }
  290.  
  291. int
  292. readgroup(char *group)
  293. {
  294.     register int ch;
  295.     register char *name;
  296.     char newname[128];
  297.  
  298.     while (name = first_unread()) {
  299.     named_art:
  300.     switch (ch = showart(group, name)) {
  301.     case 'd':
  302.     case 'D':
  303.         del_cur_art(1);
  304.         /* fall through to... */
  305.  
  306.     case 'n':
  307.     case 'N':
  308.         mark_cur_art(1);
  309.         break;
  310.  
  311.     case 'q':
  312.         free_directory(1);
  313.         return('x');
  314.     case 'Q':
  315.         free_directory(0);
  316.         return ('x');
  317.  
  318.     case '$':
  319.         free_directory(1);
  320.         return '$';
  321.  
  322.     case '-':
  323.         name = get_prev_art();
  324.         goto named_art;
  325.  
  326.     case '^':
  327.         rewind_arts();
  328.         break;
  329.  
  330.     case '0':
  331.     case '1':
  332.     case '2':
  333.     case '3':
  334.     case '4':
  335.     case '5':
  336.     case '6':
  337.     case '7':
  338.     case '8':
  339.     case '9':
  340.         newname[0] = ch;
  341.         ON;
  342.         printf("Goto Article");
  343.         OFF;
  344.         printf(" #%c", ch);
  345.         fflush(stdout);
  346.         gets(newname+1);
  347.  
  348.         if ((name = goto_article(newname)) == NULL) {
  349.         /* FIXME -- handle illegal article */
  350.         break;    /* DEBUG */
  351.         }
  352.         goto named_art;
  353.  
  354.     case '.':
  355.     case '>':
  356.     case ',':
  357.     case '<':
  358.         for(;;) {
  359.         printf("\r             #%s\t%-50s", name, subs(art2file(group, name)));
  360.         ON;
  361.         printf("\rGoto Article");
  362.         OFF;
  363.         switch (rawch()) {
  364.         case '>':
  365.         case '.':
  366.             if ((name = get_next_art()) == NULL) {
  367.             /* wrap around to begining */
  368.             name = get_next_art();
  369.             }
  370.             break;
  371.         case ',':
  372.         case '<':
  373.             name = get_prev_art();
  374.             break;
  375.         default:
  376.             goto named_art;
  377.         }
  378.         }
  379.     default:
  380.         break;
  381.     }
  382.     }
  383.     free_directory(1);
  384.     return ('n');
  385. }
  386.  
  387. void
  388. scr_inverse_on(void)
  389. {
  390.     printf("\x9b\x37;3%c;4%cm", fg, bg);
  391. }
  392.  
  393. void
  394. scr_inverse_off(void)
  395. {
  396.     printf("\x9b\x30;33;40m\033[0m");
  397. }
  398.  
  399. rawch(void)
  400. {
  401.     register int ch;
  402.  
  403.     fflush(stdout);
  404.     raw(stdin);
  405.     ch = getchar();
  406.     cooked(stdin);
  407.     return (ch);
  408. }
  409.  
  410.